<?php

declare(strict_types=1);

namespace Modules\Member\Http\Controllers;

use Api\Http\Controllers\WechatController;
use Carbon\Carbon;
use Catch\Base\CatchController as Controller;

use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Pay\Application;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use Modules\Member\Models\Members;
use Modules\Order\Models\LevelOrders;
use Modules\Order\Models\Orders;

/**
 * 会员控制器
 */
class MembersController extends Controller
{
    public function __construct(
        protected readonly Members $model
    ) {
    }

    public function index(): mixed
    {
        return $this->model->getList();
    }

    /**
     * @return mixed
     */
    public function store(Request $request)
    {
        $params = $request->all();
        $params['from'] = $params['from'] ?? 'admin'; // 后台添加

        return $this->model->storeBy($params);
    }

    /**
     * @param $id
     * @return mixed
     */
    public function show($id): mixed
    {
        return $this->model->firstBy($id)->makeHidden('password');
    }

    /**
     * @param $id
     * @param Request $request
     * @return mixed
     */
    public function update($id, Request $request): mixed
    {
        $params = $request->all();

        $oldInfo = $this->model->find($id);
        if(!empty($params['pid']) && $oldInfo->pid != $params['pid']){
            $oldTeam = Redis::hget($id,'path');
            if(!empty($oldTeam)){
                $oldPath = explode(",",$oldTeam);
                //旧上级
                foreach ($oldPath as $v){
                    $teamInfo =  Redis::hget($v,'team');
                    if(empty($teamInfo))continue;
                    $temp = [];
                    $teamInfoArr = explode(",",$teamInfo);
                    foreach ($teamInfoArr as $items){
                        $temp[] = $items;
                        if($items == $id) break;
                    }
                    if(empty($temp)) Redis::hdel($v,'team');
                    else Redis::hset($v,'team',implode(",",$temp));
                }
            }

            //新上级信息
            $path = Redis::hget($params['pid'],'path');
            $path.=",".$params['pid'];
            Redis::hset($params['id'],'path',$path);
            $pathArr = explode(",",$path); //新上级数组
            foreach ($pathArr as $v){
                $team = Redis::hget($v,'team');
                if(empty($team)){
                    $team = $id;
                }else{
                    $team .= ",".$id;
                }
                Redis::hset($v,'team',$team);
            }
        }
        if(isset($params['status']) && $params['status'] == 2){
            $params['token'] = '';
        }
        if(empty($params['is_first_login'])){
            unset($params['is_first_login']);
        }
        return $this->model->updateBy($id, $params);
    }

    /**
     * @param $id
     * @return mixed
     */
    public function destroy($id): mixed
    {
        $team = Redis::hget($id,'team');
        if($team && !empty($team)){
            $teamArr = explode(",",$team);
            foreach ($teamArr as $v){
                $memberInfo = $this->model->find($v);
                $memberInfo->pid = 0;
                $memberInfo->save();
                Redis::hdel($v,'path');
            }

        }
        $path = Redis::hget($id,'path');
        if(!empty($path)){
            $pathArr = explode(",",$path);
            foreach ($pathArr as $v){
                $pathTeam = Redis::hget($v,'team'); //每个上级的下级团队
                $pathTeam = explode(",",$pathTeam);
                $temp = [];
                foreach ($pathTeam as $item) {
                    if($id == $item){
                        continue;
                    }

                    if(!isset($team) && $id != $item){
                        $temp[] = $item;
                    }elseif(empty($team) && $id != $item){
                        $temp[] = $item;
                    }elseif(!in_array($item,$teamArr)&& $id != $item){
                        $temp[] = $item;
                    }
                }
                if(!empty($temp)){
                    Redis::hset($v,'team',implode(",",$temp));
                }else{
                    Redis::hdel($v,'team');
                }

            }
        }
        Redis::del($id);
        return $this->model->deleteBy($id);
    }

    /**
     * @param $id
     * @return bool
     */
    public function enable($id)
    {
        return $this->model->toggleBy($id);
    }

    /**
     * @throws InvalidArgumentException
     */
    public function refundLevelOrder($id)
    {
        $levelOrder = LevelOrders::where('user_id',$id)->where('status',1)->first();
        if(empty($levelOrder)){
            return '暂无订单信息';
        }
        $wechat = new WechatController();
        $app = new Application($wechat->config);
        $response = $app->getClient()->postJson("v3/refund/domestic/refunds", [
            "out_trade_no" => $levelOrder->order_sn,
            "out_refund_no" => uniqid(),
            "notify_url" => "https://api.susujilianmeng.com/kuaidi/wechat/level_callback",
            "amount" => [
                "refund" => 590,
                "total" => 590,
                "currency" => "CNY"
            ]
        ]);
      return $id;
    }

    public function agentList(Request $request,$id = ''): mixed
    {


        $city = $request->input('agent_city_name','');
        $list = $this->model->setBeforeGetList(function ($query) use ($id,$city) {
            if(!empty($city)){
                $query = $query->whereLike('agent_city_name',$city.'%');
            }
            if(!empty($id)){
                $query = $query->where('id',$id);
            }

            return $query->whereNotNull('agent_city_name')->where('agent_city_name','<>','');
        })->getList()->toArray();
        $today = [
            Carbon::now()->startOfDay()->timestamp,
            Carbon::now()->endOfDay()->timestamp
        ];
        $week = [
            Carbon::now()->startOfWeek()->timestamp,
            Carbon::now()->timestamp,
        ];

        $month = [
            Carbon::now()->startOfMonth()->copy()->startOfDay(),
            Carbon::now()->timestamp,
        ];
        $data = $list['data'];
        foreach ($data as $k=>$v){
                $todayCount = Orders::whereBetween('updated_at', $today)->whereLike('sender_city',$v['agent_city_name'])->where('type_code',3)->count();
                $weekCount = Orders::whereBetween('updated_at', $week)->whereLike('sender_city',$v['agent_city_name'])->where('type_code',3)->count();
                $monthCount = Orders::whereBetween('updated_at', $month)->whereLike('sender_city',$v['agent_city_name'])->where('type_code',3)->count();
                $data[$k]['today_count'] = $todayCount;
                $data[$k]['week_count'] = $weekCount;
                $data[$k]['month_count'] = $monthCount;
                $data[$k]['agent_start_at'] = date('Y-m-d H:i:s', $v['agent_start_at']) ?? '';
                $data[$k]['agent_end_at'] = date('Y-m-d H:i:s', $v['agent_end_at']) ?? '';

        }
        $data = array_values($data);
        $list['data'] = $data;
        return $list;
    }
    public function agentShow($id): mixed
    {
        return $this->model->firstBy($id)->makeHidden('password');

    }


    public function agentUpdate(Request $request): mixed
    {
        $params = $request->all();
        $id = $request->input('id','');
        $city = $request->input('agent_city_name','');
        if(!empty($params['agent_city_name'])){
            $agentInfo = Members::whereLike('agent_city_name',$params['agent_city_name'].'%')->first();
            if(!empty($agentInfo)){
                return 0;
            }else{
                $startNextMonet = strtotime(date('Y-m-01', strtotime('+1 month')));
                $endTime = $startNextMonet + 365*86400;
                $params['city_agent_status'] = 1;
                $params['agent_start_at'] = $startNextMonet;
                $params['agent_end_at'] = $endTime;
            }
        }
        return $this->model->updateBy($id, $params);
    }

    public function agentDelete($id): mixed
    {
        $params['agent_start_at'] = null;
        $params['city_agent_status'] = null;
        $params['agent_end_at'] = null;
        $params['agent_city_name'] = null;
        return $this->model->updateBy($id, $params);
    }


}
